﻿using log4net;
using ServerControl.Model;
using ServerControl.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerControl.Dal
{
    public class ScriptDal : DbBase
    {
        private static ILog logger = LogManager.GetLogger("ScriptDal");
        private static List<Script> scripts = new List<Script>();
        public static List<Script> Scripts
        {
            get
            {
                if (scripts == null || scripts.Count == 0)
                {
                    logger.Info("init scripts");
                    scripts = Instance.Queryable<Script>().ToList();
                }

                return scripts;
            }
        }

        public static void ResetScripts()
        {
            logger.Info("reset scripts");
            scripts = Instance.Queryable<Script>().ToList();
        }

        /// <summary>
        /// 获取脚本信息
        /// </summary>
        /// <param name="scriptId"></param>
        /// <returns></returns>
        public static Script GetScript(int scriptId)
        {
            return Scripts.Where(s => s.Id == scriptId).FirstOrDefault();
            //return Instance
            //    .Queryable<Script>()
            //    .Where(s => s.Id == scriptId)
            //    .First();
        }

        /// <summary>
        /// 获取所有脚本
        /// </summary>
        /// <returns></returns>
        public static List<Script> GetScripts()
        {
            return Scripts;
            //return Instance
            //    .Queryable<Script>()
            //    .ToList();
        }

        public static List<Script> ListPage(ref int records, int page, int limit, string name = "", string userName = "", int scriptType = 0)
        {
            return Instance
                .Queryable<Script>()
                .WhereIF(!string.IsNullOrEmpty(name), s => s.Name.Contains(name))
                .WhereIF(!string.IsNullOrEmpty(userName) && userName != "admin", s => s.UserName == userName || s.UserName == "")
                .WhereIF(scriptType != 0, s => s.ScriptType == scriptType)
                .OrderBy(s => s.Id, OrderByType.Desc)
                .ToPageList(page, limit, ref records);
        }

        public static bool Add(Script script)
        {
            var id = 0;
            var instance = Instance;

            try
            {
                script.DownloadUrl = string.IsNullOrEmpty(script.DownloadUrl) ? "" : script.DownloadUrl;
                script.NasPath = string.IsNullOrEmpty(script.NasPath) ? "" : script.NasPath;
                instance.BeginTran();
                id = instance
                .Insertable(script).IgnoreColumns(ignoreNullColumn: true)
                .ExecuteReturnIdentity();

                if (id > 0 && (script.ScriptStatus == StatusEnum.Enabled || script.AutoUpgrade == StatusEnum.Enabled))
                {
                    instance
                        .Updateable<Script>()
                        .SetColumns(s => new Script { ScriptStatus = StatusEnum.Disabled, AutoUpgrade = StatusEnum.Disabled })
                        .Where(s => s.Id != id && s.ScriptType == script.ScriptType)
                        .ExecuteCommand();
                }

                if (id > 0)
                {
                    instance.CommitTran();
                }
                else
                {
                    instance.RollbackTran();
                }
            }
            catch (Exception ex)
            {
                instance.RollbackTran();
                logger.Error(ex);
            }

            if (id > 0)
            {
                ResetScripts();
            }

            return id > 0;
        }

        public static bool Edit(Script script)
        {
            var isSuccess = false;
            var instance = Instance;

            try
            {
                script.DownloadUrl = string.IsNullOrEmpty(script.DownloadUrl) ? "" : script.DownloadUrl;
                script.NasPath = string.IsNullOrEmpty(script.NasPath) ? "" : script.NasPath;
                instance.BeginTran();

                if (script.ScriptStatus == StatusEnum.Enabled || script.AutoUpgrade == StatusEnum.Enabled)
                {
                    instance
                        .Updateable<Script>()
                        .SetColumns(s => new Script { ScriptStatus = StatusEnum.Disabled, AutoUpgrade = StatusEnum.Disabled })
                        .Where(s => s.ScriptType == script.ScriptType)
                        .ExecuteCommand();
                }

                isSuccess = instance
                    .Updateable(script)
                    .IgnoreColumns(ignoreAllNullColumns: true)
                    .IgnoreColumns(s => new { s.Id, s.AddTime })
                    .Where(s => s.Id == script.Id)
                    .ExecuteCommand() > 0;

                if (isSuccess)
                {
                    instance.CommitTran();
                }
                else
                {
                    instance.RollbackTran();
                }
            }
            catch (Exception ex)
            {
                instance.RollbackTran();
                logger.Error(ex);
            }

            if (isSuccess)
            {
                ResetScripts();
            }

            return isSuccess;
        }

        public static bool Delete(int id)
        {
            var isSuccess = Instance
                .Deleteable<Script>()
                .Where(s => s.Id == id)
                .ExecuteCommand() > 0;

            if (isSuccess)
            {
                ResetScripts();
            }

            return isSuccess;
        }
    }
}
